package service;

import model.Subject;
import model.Major;
import model.User;
import utils.DatabaseUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * SubjectService 类提供了对 subjects 表相关的操作服务，包括查询所有科目、删除科目、根据班级ID查询科目、添加科目和更新科目信息。
 */
public class SubjectService {

    /**
     * 获取所有科目信息，并与 majors 表进行左连接以获取专业名称。
     * @return 返回一个包含所有科目的列表。
     */
    public List<Subject> getAllSubjects() {
        List<Subject> subjects = new ArrayList<>();
        String sql = "SELECT s.*, m.major_name FROM subjects s " +
                "LEFT JOIN majors m ON s.major_code = m.major_code " +
                "ORDER BY s.subject_code"; // 按科目代码排序

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             Statement stmt = conn.createStatement(); // 创建SQL语句对象
             ResultSet rs = stmt.executeQuery(sql)) { // 执行查询语句

            while (rs.next()) { // 遍历查询结果集
                Subject subject = new Subject();
                subject.setId(rs.getInt("id")); // 设置科目ID
                subject.setSubjectCode(rs.getString("subject_code")); // 设置科目代码
                subject.setSubjectName(rs.getString("subject_name")); // 设置科目名称
                subject.setCredits(rs.getDouble("credits")); // 设置学分
                subject.setHours(rs.getInt("hours")); // 设置学时
                subject.setMajorCode(rs.getString("major_code")); // 设置专业代码
                subject.setMajorName(rs.getString("major_name")); // 设置专业名称
                subject.setCreatedAt(rs.getTimestamp("created_at")); // 设置创建时间
                subjects.add(subject); // 将科目对象添加到列表中
            }
        } catch (SQLException e) {
            e.printStackTrace(); // 打印SQL异常信息
        }
        return subjects; // 返回科目列表
    }

    /**
     * 根据ID删除指定科目。
     * @param subjectId 要删除的科目的ID。
     * @return 如果成功删除，则返回 true；否则返回 false。
     */
    public boolean deleteSubject(int subjectId) {
        String sql = "DELETE FROM subjects WHERE id = ?"; // 删除语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement pstmt = conn.prepareStatement(sql)) { // 创建预编译SQL语句对象

            pstmt.setInt(1, subjectId); // 设置参数
            return pstmt.executeUpdate() > 0; // 执行更新操作并判断是否成功
        } catch (SQLException e) {
            e.printStackTrace(); // 打印SQL异常信息
            return false; // 返回失败
        }
    }

    /**
     * 根据班级ID查询该班级的所有科目信息。
     * @param classId 班级ID。
     * @return 返回一个包含指定班级所有科目的列表。
     */
    public List<Subject> getSubjectsByClassId(int classId) {
        List<Subject> subjects = new ArrayList<>();
        String sql = "SELECT s.* FROM subjects s " +
                "JOIN class_subjects cs ON s.id = cs.subject_id " +
                "WHERE cs.class_id = ?"; // 查询指定班级的科目

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建预编译SQL语句对象

            stmt.setInt(1, classId); // 设置参数
            ResultSet rs = stmt.executeQuery(); // 执行查询语句

            while (rs.next()) { // 遍历查询结果集
                Subject subject = new Subject();
                subject.setId(rs.getInt("id")); // 设置科目ID
                subject.setSubjectCode(rs.getString("subject_code")); // 设置科目代码
                subject.setSubjectName(rs.getString("subject_name")); // 设置科目名称
                subject.setCredits(rs.getDouble("credits")); // 设置学分
                subject.setHours(rs.getInt("hours")); // 设置学时
                subject.setMajorCode(rs.getString("major_code")); // 设置专业代码
                subjects.add(subject); // 将科目对象添加到列表中
            }
        } catch (SQLException e) {
            e.printStackTrace(); // 打印SQL异常信息
        }
        return subjects; // 返回科目列表
    }

    /**
     * 添加一个新的科目到 subjects 表中。
     * @param code 科目代码。
     * @param name 科目名称。
     * @param credits 学分。
     * @param hours 学时。
     * @param majorCode 专业代码。
     * @return 如果成功添加，则返回 true；否则返回 false。
     */
    public boolean addSubject(String code, String name, double credits, int hours, String majorCode) {
        String sql = "INSERT INTO subjects (subject_code, subject_name, credits, hours, major_code, created_at) " +
                "VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)"; // 插入语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建预编译SQL语句对象

            stmt.setString(1, code); // 设置科目代码
            stmt.setString(2, name); // 设置科目名称
            stmt.setDouble(3, credits); // 设置学分
            stmt.setInt(4, hours); // 设置学时
            stmt.setString(5, majorCode); // 设置专业代码

            return stmt.executeUpdate() > 0; // 执行更新操作并判断是否成功
        } catch (SQLException e) {
            e.printStackTrace(); // 打印SQL异常信息
            return false; // 返回失败
        }
    }

    /**
     * 根据ID查询指定科目的详细信息。
     * @param id 科目ID。
     * @return 返回指定ID的科目对象；如果未找到，则返回 null。
     */
    public Subject getSubjectById(int id) {
        String sql = "SELECT s.*, m.major_name FROM subjects s " +
                "LEFT JOIN majors m ON s.major_code = m.major_code " +
                "WHERE s.id = ?"; // 查询指定ID的科目

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建预编译SQL语句对象

            stmt.setInt(1, id); // 设置参数
            ResultSet rs = stmt.executeQuery(); // 执行查询语句

            if (rs.next()) { // 如果找到结果
                Subject subject = new Subject();
                subject.setId(rs.getInt("id")); // 设置科目ID
                subject.setSubjectCode(rs.getString("subject_code")); // 设置科目代码
                subject.setSubjectName(rs.getString("subject_name")); // 设置科目名称
                subject.setCredits(rs.getDouble("credits")); // 设置学分
                subject.setHours(rs.getInt("hours")); // 设置学时
                subject.setMajorCode(rs.getString("major_code")); // 设置专业代码
                subject.setMajorName(rs.getString("major_name")); // 设置专业名称
                subject.setCreatedAt(rs.getTimestamp("created_at")); // 设置创建时间
                return subject; // 返回科目对象
            }
        } catch (SQLException e) {
            e.printStackTrace(); // 打印SQL异常信息
        }
        return null; // 返回空
    }

    /**
     * 更新指定科目的信息。
     * @param subject 包含更新信息的 Subject 对象。
     * @return 如果成功更新，则返回 true；否则返回 false。
     */
    public boolean updateSubject(Subject subject) {
        String sql = "UPDATE subjects SET subject_name = ?, credits = ?, " +
                "hours = ?, major_code = ? WHERE id = ?"; // 更新语句

        try (Connection conn = DatabaseUtil.getConnection(); // 获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(sql)) { // 创建预编译SQL语句对象

            stmt.setString(1, subject.getSubjectName()); // 设置科目名称
            stmt.setDouble(2, subject.getCredits()); // 设置学分
            stmt.setInt(3, subject.getHours()); // 设置学时
            stmt.setString(4, subject.getMajorCode()); // 设置专业代码
            stmt.setInt(5, subject.getId()); // 设置科目ID

            return stmt.executeUpdate() > 0; // 执行更新操作并判断是否成功
        } catch (SQLException e) {
            e.printStackTrace(); // 打印SQL异常信息
            return false; // 返回失败
        }
    }
}
